/*
	This file is part of libswirl
*/
#include "license/bsd"


#include "types.h"
#include "gl3w.h"

#if defined(SUPPORT_EGL)
#include "khronos/EGL/egl.h"
#if defined(_ANDROID)
#include <dlfcn.h>
#endif
#endif

#if defined(SUPPORT_SDL)
#include <SDL2/SDL.h>
#endif

struct rglgen_sym_map { const char *sym; void *ptr; };
extern const struct rglgen_sym_map rglgen_symbol_map[];

bool load_gles_symbols()
{
	#if defined(SUPPORT_EGL) ||  defined(SUPPORT_SDL)
		for (int i = 0; rglgen_symbol_map[i].sym != NULL; i++)
		{
		    *(void **)rglgen_symbol_map[i].ptr = nullptr;
#if defined(_ANDROID)
		    //try to load via dlsym -- older android can't load everything via eglGetProcAddress
		    *(void **)rglgen_symbol_map[i].ptr = (void*)dlsym(RTLD_DEFAULT, rglgen_symbol_map[i].sym);
#endif

#if defined(SUPPORT_EGL)
		    // try to load via eglGetProcAddress
		    if (!*(void **)rglgen_symbol_map[i].ptr) {
		      *(void **)rglgen_symbol_map[i].ptr = (void*)eglGetProcAddress(rglgen_symbol_map[i].sym);
		    }
#endif

#if defined(SUPPORT_SDL)
		    // try to load via eglGetProcAddress
		    if (!*(void **)rglgen_symbol_map[i].ptr) {
		      *(void **)rglgen_symbol_map[i].ptr = (void*)SDL_GL_GetProcAddress(rglgen_symbol_map[i].sym);
		    }
#endif

            // print a warning if failed
            if (!*(void **)rglgen_symbol_map[i].ptr)
            {
                printf("WARN: load_gles_symbols: failed to resolve %s\n", rglgen_symbol_map[i].sym);
            }
	    }
        return true;
    #else
        return false;    
    #endif
}

#define SYM(x) { "gl" #x, &(gl##x) }
const struct rglgen_sym_map rglgen_symbol_map[] = {
    SYM(ActiveTexture),
    SYM(AttachShader),
    SYM(BindAttribLocation),
    SYM(BindBuffer),
    SYM(BindFramebuffer),
    SYM(BindRenderbuffer),
    SYM(BindTexture),
    SYM(BlendColor),
    SYM(BlendEquation),
    SYM(BlendEquationSeparate),
    SYM(BlendFunc),
    SYM(BlendFuncSeparate),
    SYM(BufferData),
    SYM(BufferSubData),
    SYM(CheckFramebufferStatus),
    SYM(Clear),
    SYM(ClearColor),
    SYM(ClearDepthf),
    SYM(ClearStencil),
    SYM(ColorMask),
    SYM(CompileShader),
    SYM(CompressedTexImage2D),
    SYM(CompressedTexSubImage2D),
    SYM(CopyTexImage2D),
    SYM(CopyTexSubImage2D),
    SYM(CreateProgram),
    SYM(CreateShader),
    SYM(CullFace),
    SYM(DeleteBuffers),
    SYM(DeleteFramebuffers),
    SYM(DeleteProgram),
    SYM(DeleteRenderbuffers),
    SYM(DeleteShader),
    SYM(DeleteTextures),
    SYM(DepthFunc),
    SYM(DepthMask),
    SYM(DepthRangef),
    SYM(DetachShader),
    SYM(Disable),
    SYM(DisableVertexAttribArray),
    SYM(DrawArrays),
    SYM(DrawElements),
    SYM(Enable),
    SYM(EnableVertexAttribArray),
    SYM(Finish),
    SYM(Flush),
    SYM(FramebufferRenderbuffer),
    SYM(FramebufferTexture2D),
    SYM(FrontFace),
    SYM(GenBuffers),
    SYM(GenerateMipmap),
    SYM(GenFramebuffers),
    SYM(GenRenderbuffers),
    SYM(GenTextures),
    SYM(GetActiveAttrib),
    SYM(GetActiveUniform),
    SYM(GetAttachedShaders),
    SYM(GetAttribLocation),
    SYM(GetBooleanv),
    SYM(GetBufferParameteriv),
    SYM(GetError),
    SYM(GetFloatv),
    SYM(GetFramebufferAttachmentParameteriv),
    SYM(GetIntegerv),
    SYM(GetProgramiv),
    SYM(GetProgramInfoLog),
    SYM(GetRenderbufferParameteriv),
    SYM(GetShaderiv),
    SYM(GetShaderInfoLog),
    SYM(GetShaderPrecisionFormat),
    SYM(GetShaderSource),
    SYM(GetString),
    SYM(GetTexParameterfv),
    SYM(GetTexParameteriv),
    SYM(GetUniformfv),
    SYM(GetUniformiv),
    SYM(GetUniformLocation),
    SYM(GetVertexAttribfv),
    SYM(GetVertexAttribiv),
    SYM(GetVertexAttribPointerv),
    SYM(Hint),
    SYM(IsBuffer),
    SYM(IsEnabled),
    SYM(IsFramebuffer),
    SYM(IsProgram),
    SYM(IsRenderbuffer),
    SYM(IsShader),
    SYM(IsTexture),
    SYM(LineWidth),
    SYM(LinkProgram),
    SYM(PixelStorei),
    SYM(PolygonOffset),
    SYM(ReadPixels),
    SYM(ReleaseShaderCompiler),
    SYM(RenderbufferStorage),
    SYM(SampleCoverage),
    SYM(Scissor),
    SYM(ShaderBinary),
    SYM(ShaderSource),
    SYM(StencilFunc),
    SYM(StencilFuncSeparate),
    SYM(StencilMask),
    SYM(StencilMaskSeparate),
    SYM(StencilOp),
    SYM(StencilOpSeparate),
    SYM(TexImage2D),
    SYM(TexParameterf),
    SYM(TexParameterfv),
    SYM(TexParameteri),
    SYM(TexParameteriv),
    SYM(TexSubImage2D),
    SYM(Uniform1f),
    SYM(Uniform1fv),
    SYM(Uniform1i),
    SYM(Uniform1iv),
    SYM(Uniform2f),
    SYM(Uniform2fv),
    SYM(Uniform2i),
    SYM(Uniform2iv),
    SYM(Uniform3f),
    SYM(Uniform3fv),
    SYM(Uniform3i),
    SYM(Uniform3iv),
    SYM(Uniform4f),
    SYM(Uniform4fv),
    SYM(Uniform4i),
    SYM(Uniform4iv),
    SYM(UniformMatrix2fv),
    SYM(UniformMatrix3fv),
    SYM(UniformMatrix4fv),
    SYM(UseProgram),
    SYM(ValidateProgram),
    SYM(VertexAttrib1f),
    SYM(VertexAttrib1fv),
    SYM(VertexAttrib2f),
    SYM(VertexAttrib2fv),
    SYM(VertexAttrib3f),
    SYM(VertexAttrib3fv),
    SYM(VertexAttrib4f),
    SYM(VertexAttrib4fv),
    SYM(VertexAttribPointer),
    SYM(Viewport),
    SYM(ReadBuffer),
    SYM(DrawRangeElements),
    SYM(TexImage3D),
    SYM(TexSubImage3D),
    SYM(CopyTexSubImage3D),
    SYM(CompressedTexImage3D),
    SYM(CompressedTexSubImage3D),
    SYM(GenQueries),
    SYM(DeleteQueries),
    SYM(IsQuery),
    SYM(BeginQuery),
    SYM(EndQuery),
    SYM(GetQueryiv),
    SYM(GetQueryObjectuiv),
    SYM(UnmapBuffer),
    SYM(GetBufferPointerv),
    SYM(DrawBuffers),
    SYM(UniformMatrix2x3fv),
    SYM(UniformMatrix3x2fv),
    SYM(UniformMatrix2x4fv),
    SYM(UniformMatrix4x2fv),
    SYM(UniformMatrix3x4fv),
    SYM(UniformMatrix4x3fv),
    SYM(BlitFramebuffer),
    SYM(RenderbufferStorageMultisample),
    SYM(FramebufferTextureLayer),
    SYM(MapBufferRange),
    SYM(FlushMappedBufferRange),
    SYM(BindVertexArray),
    SYM(DeleteVertexArrays),
    SYM(GenVertexArrays),
    SYM(IsVertexArray),
    SYM(GetIntegeri_v),
    SYM(BeginTransformFeedback),
    SYM(EndTransformFeedback),
    SYM(BindBufferRange),
    SYM(BindBufferBase),
    SYM(TransformFeedbackVaryings),
    SYM(GetTransformFeedbackVarying),
    SYM(VertexAttribIPointer),
    SYM(GetVertexAttribIiv),
    SYM(GetVertexAttribIuiv),
    SYM(VertexAttribI4i),
    SYM(VertexAttribI4ui),
    SYM(VertexAttribI4iv),
    SYM(VertexAttribI4uiv),
    SYM(GetUniformuiv),
    SYM(GetFragDataLocation),
    SYM(Uniform1ui),
    SYM(Uniform2ui),
    SYM(Uniform3ui),
    SYM(Uniform4ui),
    SYM(Uniform1uiv),
    SYM(Uniform2uiv),
    SYM(Uniform3uiv),
    SYM(Uniform4uiv),
    SYM(ClearBufferiv),
    SYM(ClearBufferuiv),
    SYM(ClearBufferfv),
    SYM(ClearBufferfi),
    SYM(GetStringi),
    SYM(CopyBufferSubData),
    SYM(GetUniformIndices),
    SYM(GetActiveUniformsiv),
    SYM(GetUniformBlockIndex),
    SYM(GetActiveUniformBlockiv),
    SYM(GetActiveUniformBlockName),
    SYM(UniformBlockBinding),
    SYM(DrawArraysInstanced),
    SYM(DrawElementsInstanced),
    SYM(FenceSync),
    SYM(IsSync),
    SYM(DeleteSync),
    SYM(ClientWaitSync),
    SYM(WaitSync),
    SYM(GetInteger64v),
    SYM(GetSynciv),
    SYM(GetInteger64i_v),
    SYM(GetBufferParameteri64v),
    SYM(GenSamplers),
    SYM(DeleteSamplers),
    SYM(IsSampler),
    SYM(BindSampler),
    SYM(SamplerParameteri),
    SYM(SamplerParameteriv),
    SYM(SamplerParameterf),
    SYM(SamplerParameterfv),
    SYM(GetSamplerParameteriv),
    SYM(GetSamplerParameterfv),
    SYM(VertexAttribDivisor),
    SYM(BindTransformFeedback),
    SYM(DeleteTransformFeedbacks),
    SYM(GenTransformFeedbacks),
    SYM(IsTransformFeedback),
    SYM(PauseTransformFeedback),
    SYM(ResumeTransformFeedback),
    SYM(GetProgramBinary),
    SYM(ProgramBinary),
    SYM(ProgramParameteri),
    SYM(InvalidateFramebuffer),
    SYM(InvalidateSubFramebuffer),
    SYM(TexStorage2D),
    SYM(TexStorage3D),
    SYM(GetInternalformativ),
    SYM(DispatchCompute),
    SYM(DispatchComputeIndirect),
    SYM(DrawArraysIndirect),
    SYM(DrawElementsIndirect),
    SYM(FramebufferParameteri),
    SYM(GetFramebufferParameteriv),
    SYM(GetProgramInterfaceiv),
    SYM(GetProgramResourceIndex),
    SYM(GetProgramResourceName),
    SYM(GetProgramResourceiv),
    SYM(GetProgramResourceLocation),
    SYM(UseProgramStages),
    SYM(ActiveShaderProgram),
    SYM(CreateShaderProgramv),
    SYM(BindProgramPipeline),
    SYM(DeleteProgramPipelines),
    SYM(GenProgramPipelines),
    SYM(IsProgramPipeline),
    SYM(GetProgramPipelineiv),
    SYM(ProgramUniform1i),
    SYM(ProgramUniform2i),
    SYM(ProgramUniform3i),
    SYM(ProgramUniform4i),
    SYM(ProgramUniform1ui),
    SYM(ProgramUniform2ui),
    SYM(ProgramUniform3ui),
    SYM(ProgramUniform4ui),
    SYM(ProgramUniform1f),
    SYM(ProgramUniform2f),
    SYM(ProgramUniform3f),
    SYM(ProgramUniform4f),
    SYM(ProgramUniform1iv),
    SYM(ProgramUniform2iv),
    SYM(ProgramUniform3iv),
    SYM(ProgramUniform4iv),
    SYM(ProgramUniform1uiv),
    SYM(ProgramUniform2uiv),
    SYM(ProgramUniform3uiv),
    SYM(ProgramUniform4uiv),
    SYM(ProgramUniform1fv),
    SYM(ProgramUniform2fv),
    SYM(ProgramUniform3fv),
    SYM(ProgramUniform4fv),
    SYM(ProgramUniformMatrix2fv),
    SYM(ProgramUniformMatrix3fv),
    SYM(ProgramUniformMatrix4fv),
    SYM(ProgramUniformMatrix2x3fv),
    SYM(ProgramUniformMatrix3x2fv),
    SYM(ProgramUniformMatrix2x4fv),
    SYM(ProgramUniformMatrix4x2fv),
    SYM(ProgramUniformMatrix3x4fv),
    SYM(ProgramUniformMatrix4x3fv),
    SYM(ValidateProgramPipeline),
    SYM(GetProgramPipelineInfoLog),
    SYM(BindImageTexture),
    SYM(GetBooleani_v),
    SYM(MemoryBarrier),
    SYM(MemoryBarrierByRegion),
    SYM(TexStorage2DMultisample),
    SYM(GetMultisamplefv),
    SYM(SampleMaski),
    SYM(GetTexLevelParameteriv),
    SYM(GetTexLevelParameterfv),
    SYM(BindVertexBuffer),
    SYM(VertexAttribFormat),
    SYM(VertexAttribIFormat),
    SYM(VertexAttribBinding),
    SYM(VertexBindingDivisor),
    SYM(BlendBarrier),
    SYM(CopyImageSubData),
    SYM(DebugMessageControl),
    SYM(DebugMessageInsert),
    SYM(DebugMessageCallback),
    SYM(GetDebugMessageLog),
    SYM(PushDebugGroup),
    SYM(PopDebugGroup),
    SYM(ObjectLabel),
    SYM(GetObjectLabel),
    SYM(ObjectPtrLabel),
    SYM(GetObjectPtrLabel),
    SYM(GetPointerv),
    SYM(Enablei),
    SYM(Disablei),
    SYM(BlendEquationi),
    SYM(BlendEquationSeparatei),
    SYM(BlendFunci),
    SYM(BlendFuncSeparatei),
    SYM(ColorMaski),
    SYM(IsEnabledi),
    SYM(DrawElementsBaseVertex),
    SYM(DrawRangeElementsBaseVertex),
    SYM(DrawElementsInstancedBaseVertex),
    SYM(FramebufferTexture),
    SYM(PrimitiveBoundingBox),
    SYM(GetGraphicsResetStatus),
    SYM(ReadnPixels),
    SYM(GetnUniformfv),
    SYM(GetnUniformiv),
    SYM(GetnUniformuiv),
    SYM(MinSampleShading),
    SYM(PatchParameteri),
    SYM(TexParameterIiv),
    SYM(TexParameterIuiv),
    SYM(GetTexParameterIiv),
    SYM(GetTexParameterIuiv),
    SYM(SamplerParameterIiv),
    SYM(SamplerParameterIuiv),
    SYM(GetSamplerParameterIiv),
    SYM(GetSamplerParameterIuiv),
    SYM(TexBuffer),
    SYM(TexBufferRange),
    SYM(TexStorage3DMultisample),

    { nullptr, nullptr },
};